package asruby.runtime
{
public interface IDynamicScope
{
    function  growIfNeeded(): void 

    // Helper function to give a good view of current dynamic scope with captured scopes
    function toString( buf:StringBuffer,  indent:String):String;
    
    function  cloneScope(): IDynamicScope; 

    function  getValues(): Array; 
    
    /**
     * Get value from current scope or one of its captured scopes.
     * 
     * FIXME: block variables are not getting primed to nil so we need to null check those
     *  until we prime them properly.  Also add assert back in.
     * 
     * @param offset zero-indexed value that represents where variable lives
     * @param depth how many captured scopes down this variable should be set
     * @return the value here
     */
    function getValue(offset:int , depth:int):IRubyObject;
    
    /**
     * Variation of getValue that checks for nulls, returning and setting the given value (presumably nil)
     */
    function getValueOrNil(offset:int, depth:int,  nil:IRubyObject):IRubyObject;
    
    /**
     * getValueOrNil for depth 0
     */
    function getValueDepthZeroOrNil( offset:int,  nil:IRubyObject ):IRubyObject;
    
    /**
     * getValueOrNil for index 0, depth 0
     */
    function getValueZeroDepthZeroOrNil( nil:IRubyObject):IRubyObject;
    
    /**
     * getValueOrNil for index 1, depth 0
     */
    function getValueOneDepthZeroOrNil(nil:IRubyObject):IRubyObject;

    /**
     * Set value in current dynamic scope or one of its captured scopes.
     * 
     * @param offset zero-indexed value that represents where variable lives
     * @param value to set
     * @param depth how many captured scopes down this variable should be set
     */
    function setValue(offset:int, value:IRubyObject, depth:int):void;

    /**
     * setValue for depth zero
     * 
     * @param offset zero-indexed value that represents where variable lives
     * @param value to set
     * @param depth how many captured scopes down this variable should be set
     */
    function setValueDepthZero(value:IRubyObject, offset:int):void;

    /**
     * Set value in current dynamic scope or one of its captured scopes.
     * 
     * @param offset zero-indexed value that represents where variable lives
     * @param value to set
     * @param depth how many captured scopes down this variable should be set
     */
    function setValueZeroDepthZero( value:IRubyObject):void;

    /**
     * Set value in current dynamic scope or one of its captured scopes.
     * 
     * @param offset zero-indexed value that represents where variable lives
     * @param value to set
     * @param depth how many captured scopes down this variable should be set
     */
    function  setValueOneDepthZero( value:IRubyObject):void;

    /**
     * Set all values which represent 'normal' parameters in a call list to this dynamic
     * scope.  Function calls bind to local scopes by assuming that the indexes or the
     * arg list correspond to that of the local scope (plus 2 since $_ and $~ always take
     * the first two slots).  We pass in a second argument because we sometimes get more
     * values than we are expecting.  The rest get compacted by original caller into 
     * rest args.
     * 
     * @param values up to size specified to be mapped as ordinary parm values
     * @param size is the number of values to assign as ordinary parm values
     */
    function setArgValues( values:Array, size:int):IRubyObject;

    /**
     * Copy variable values back for ZSuper call.
     */
    function getArgValues(): Array;		
}
}